public class Test {

   /* 实现多态，必须满足三个条件：
    1.在继承体系下
    2.子类重写父类的方法
    3.通过父类的引用调用重写的方法（向上转型）*/


    //向上转型的使用：
    //1.直接赋值
   /* public static void main1_1(String[] args) {
        //父类引用 引用了 子类对象。之所以可以，是因为Dog是Animal的子类
        Animal animal = new Dog("柴犬",1);
        //     大的类型 = 小的类型  （狗是一种动物）
    }
    //2.参数的传递
    public static void func1(Animal animal){

    }
    public static void main1_2(String[] args) {
        Dog dog = new Dog("柴犬",1);
        func1(dog);
    }
    //3.返回值
    public static Animal func2(){
        return new Dog("柴犬",1);
    }*/

    public static void main2(String[] args) {
        Animal animal = new Dog("柴犬",1);
       /* animal.bark(); //虽然父类引用引用了子类对象，但是通过父类引用只能访问父类自己的属性和方法
        animal.color*/
        animal.eat();//通过父类引用调用了重写的方法，这种行为叫动态绑定/运行时绑定
    }

    public static void eatting(Animal animal){
        animal.eat(); //③
        // 同一个引用animal，同一个方法，引用的对象不一样，
        // 调用同一个方法所表现的行为不一样，这种思想称为多态！[ ① 向上转型 ② 发生重写 ③ 动态绑定 ]
    }
    public static void main3(String[] args) {
        Dog dog = new Dog("柯基",1);
        eatting(dog); //①

        Cat cat = new Cat("咪咪",3);
        eatting(cat);
    }

    //向下转型
    public static void main4_1(String[] args) {
        Animal animal = new Dog("柴犬", 1);
        Dog dog = (Dog) animal;
        dog.bark(); //输出 柴犬 正在汪汪叫... animal本来指向的就是狗，因此将animal还原为狗也是安全的
        System.out.println("===========");
       /* Cat cat = (Cat) animal;
        cat.mew();*/  //可以通过编译，运行时抛出ClassCastException异常，因为animal实际指向的是狗。
        // 现在要强制还原为猫，⽆法正常还原，运⾏时抛出：ClassCastException
    }

    public static void main4_2(String[] args){
        Animal animal = new Cat("布偶猫",2);

        //Java中为了提⾼向下转型的安全性，引⼊了 instanceof ，如果该表达式为true，则可以安全转换
        if(animal instanceof Cat){ //animal是否引用了Cat这个类型的对象，是true，否false
            Cat cat = (Cat) animal;
            cat.mew();
        }else{
            System.out.println("animal not instanceof Cat");
        }
        System.out.println("==========");

        if(animal instanceof Dog){
            Dog dog = (Dog) animal;
            dog.bark();
        }else{
            System.out.println("animal not instanceof Dog");
        }

    }

}